#include <stdio.h>
#include <string.h>

#define instr_recs  instr_recs1
#define ext_instr_recs  ext_instr_recs1
#define x87_instr_recs  x87_instr_recs2
#include "instr_db.h"
#include "instr_dat.h"

static struct instr_rec instr_desc;
int get_instr_desc(unsigned char * opcode);
int get_ext_instr_desc(unsigned char * opcode);
int mk_flag(OPERAND_TYPE op_type);
int basic_len(int flag);
char * op_str(OPERAND_TYPE op_type);
	char * 	genfastpath_code();
static FILE* fp;
void print_uop (bool b_rm,bool b_dir);
void print_alu (bool b_rm,bool b_dir);
#undef INSTR_REC
#define INSTR_REC(x) #x,

char *  instr_name[]= {
#include "instr_id_def.h"
"unused"
};

#undef FUNIT_REC
#define FUNIT_REC(x) #x,

char *  funit_name[]={
#include "funit_def.h"
"misc"
};

#undef OPER_TYPE_REC
#define OPER_TYPE_REC(x) #x,
//
// If new oper type is to be defined, go to oper_type.h
//
char * operand_type_name[]= {
#include "oper_type_def.h"
"unused"
};

static void print_case()
{
	if (0xff==instr_desc.mask)
		fprintf(fp,"if( 0x%x==code[0]// %s   %s %s\n",instr_desc.id,instr_desc.mnemonics,op_str(instr_desc.src1),op_str(instr_desc.src2));
	else
		fprintf(fp,"if( 0x%x==(code[0]& 0x%x)// %s   %s %s\n",instr_desc.id,instr_desc.mask,instr_desc.mnemonics,op_str(instr_desc.src1),op_str(instr_desc.src2));

	//
	//id2
	//
	if (0xff!=instr_desc.id2)
	{
		//if (instr_desc.id<8)
			fprintf(fp,"&&0x%x==((code[1]>>3)&7) \n",instr_desc.id2);
		//else
		//	fprintf(fp,"&&0x%x== code[1] \n",instr_desc.id2);
	}

	//
	//pmodeonly?
	//
	if (instr_desc.pmodeonly)
		fprintf(fp,"&&pmode \n");

	//
	//lockable?
	//
	if (!instr_desc.lockable)
		fprintf(fp,"&&0==(prefix&PREFIX_LOCK) \n");
	//
	//repeatable?
	//
	if (!instr_desc.repeatable)
		fprintf(fp,"&&0==(prefix&(PREFIX_REPZ| PREFIX_REPNZ))\n");


}

int __cdecl  gen_decode()
{
	//FILE *fp;
	fp = fopen("\\whb\\disasmx86\\isa-simu-core\\decode_inst.cpp","wt");
	if(fp)
	{
		fprintf(fp,"\n\n#include \"common.h\"\n\n"
		           "#include \"uop.h\"\n\n"
					"#undef FUNIT_REC\n"
					"#define FUNIT_REC(x) x,\n"
					"enum FUNIT {\n"
					"#include \"funit_def.h\"\n"
					"misc\n"
					"};\n"
			       "#undef INSTR_REC\n"
                   "#define INSTR_REC(x) x,\n"
				   "\n"
                   "enum INSTR_ID {\n"
                   "#include \"instr_id_def.h\"\n"
                   " unused\n"
                    "};\n");

		fprintf(fp,"void  decode(int &n_uop,int addr_size, int data_size ,unsigned char * code,bool pmode,bool &illegal,char prefix,UOP uop[5],unsigned int next_ip)\n"
		           "{\n"
				   "  bool stack;\n"
				   "  int op_size;\n"
				   "  char seg=prefix &7;\n"
				   "  int imm;\n"
				   "  RoV r_v0={false};\n"
				   "  const int TMP0=0x80;\n"
				   "  const int TMP1=0x81;\n"


				   "    for (int i=0;i<5;i++)\n"
				   "    for (int j=0;j<3;j++)\n"
				   "  	  uop[i].src[j]=r_v0;\n"
				    );


		fprintf(fp,"if (code[0]==0x0f )\n{\ncode ++;\n");
		for(int i=0; i <sizeof (ext_instr_recs)/sizeof (ext_instr_recs[0]);i++)
		{
			int dir, rmm;
			instr_desc = ext_instr_recs[i];
			
			if ( instr_desc.index==unused) continue;
	
			if (instr_desc.src1<rm_max
			 ||instr_desc.src2<rm_max
			 ||instr_desc.dst<rm_max)
			 rmm =1; else rmm =0;



			do 
			{

			if(instr_desc.dir_mask)dir =1; else dir =0;

			
			do 
			{

			print_case();

			if(instr_desc.dir_mask)
				fprintf(fp,"&&(code[0] &0x%x)==0x%x",instr_desc.dir_mask,dir ? instr_desc.dir_mask:0);

			if(instr_desc.src1 < rm_max) 
				fprintf (fp, rmm? "&&(((code[1]>>6)&3)!=3)// rm indicates mem\n":"&&(((code[1]>>6)&3)==3)// rm indicates  reg\n");
			

			fprintf(fp,"){ \n");

			//
			//decode operands
			//
			print_uop (rmm==1,dir==1);

			fprintf(fp,"\n__asm int 3;\nreturn;// %s(code,data_size,addr_size,prefix);\n",instr_name[instr_desc.index]);	

			fprintf(fp,"\n}\n//else\n");


			} while (dir--);
			} while (rmm--);

			//
			//decode operands
			//

		}

		fprintf(fp,"\n{\n __asm int 3;\n}\n}\n else\n{\n");


		//
		// alu
		//
		for(int i=0; i <sizeof (instr_recs)/sizeof (instr_recs[0]);i++)
		{
			int dir, rmm;
			instr_desc = instr_recs[i];

			if ( instr_desc.index==unused) continue;
	
			if (instr_desc.src1<rm_max
			 ||instr_desc.src2<rm_max
			 ||instr_desc.dst<rm_max)
			 rmm =1; else rmm =0;



			do 
			{

			if(instr_desc.dir_mask)dir =1; else dir =0;

			
			do 
			{

			print_case();

			if(instr_desc.dir_mask)
				fprintf(fp,"&&(code[0] &0x%x)==0x%x",instr_desc.dir_mask,dir ? instr_desc.dir_mask:0);

			if(instr_desc.src1 < rm_max) 
				fprintf (fp, rmm? "&&(((code[1]>>6)&3)!=3)// rm indicates mem\n":"&&(((code[1]>>6)&3)==3)// rm indicates  reg\n");
			

			fprintf(fp,"){ \n");

			//
			//decode operands
			//
			print_uop (rmm==1,dir==1);
			fprintf(fp,"__asm int 3;\nreturn;// %s(code,data_size,addr_size,prefix);\n",instr_name[instr_desc.index]);
			fprintf(fp,"}//else\n");


			} while (dir--);
			} while (rmm--);
		}
		fprintf(fp,"\n{\n __asm int 3;\n}\n}\n}\n");	
		




	fclose(fp);
	return 1;
	}

	return 0;

}
char * op_str(OPERAND_TYPE op_type)
{
char*s;

switch (op_type)
{
case acc     :    s="acc";break;
case reg_dx  :    s="dx";break;  
case reg_cl  :   s="cl";break;  
case const_1 :    s="1";break; 
case const_3 :   s="3";break;  
case sreg    :    s="sreg";break;
case reg     :   s="r";break;

case imp_al     :   s="al";break;
case imp_ah     :   s="ah";break;
case imp_ax     :   
case imp_acc    :
case imp_hacc   :
case imp_dacc   :   s="acc";break;
case dontcare   :
case op1       :
case none      :   s="";break;


case fs_gs     :    s="fs/gs";break;
case rm      :  
case rm1      :  
case rm2      :  
case rm8      :  
case rm16     :  
case rmf      : s="rm";break;
case r16       : s="r16";break; 
  
case rm_r32   :  s="r";break; 
case rm_cr     : s="cr";break; 
case rm_dr     :  s="dr";break;
case rm_tr     : s="tr";break; 
case rm_sreg   : s="sreg";break; 
case imm_8     : s="imm8";break;
case rel_8     :  s="rel8";break;
case imm_16    : s="imm16";break;
case rel_16    : s="rel";break;
case mem_off   : s="[disp]";break; 

case imm_far   :  s="ptr16:16/32";break;

case rel       : s="rel";break; 

case imm       :  s="imm";break;

default    :
	s="";
}

return s;
}










/*


                  TABLE 1
    ______________________________________
    x86 Fast Path, Double Dispatch, and MROM Instructions
    X86 Instruction   Instruction Category
    ______________________________________
    AAA               MROM
    AAD               MROM
    AAM               MROM
    AAS               MROM
    ADC               fast path
    ADD               fast path
    AND               fast path
    ARPL              MROM
    BOUND             MROM
    BSF               fast path
    BSR               fast path
    BSWAP             MROM
    BT                fast path
    BTC               fast path
    BTR               fast path
    BTS               fast path
    CALL              fast path/double dispatch
    CBW               fast path
    CWDE              fast path
    CLC               fast path
    CLD               fast path
    CLI               MROM
    CLTS              MROM
    CMC               fast path
    CMP               fast path
    CMPS              MROM
    CMPSB             MROM
    CMPSW             MROM
    CMPSD             MROM
    CMPXCHG           MROM
    CMPXCHG8B         MROM
    CPUID             MROM
    CWD               MROM
    CWQ               MROM
    DDA               MROM
    DAS               MROM
    DEC               fast path
    DIV               MROM
    ENTER             MROM
    HLT               MROM
    IDIV              MROM
    IMUL              double dispatch
    IN                MROM
    INC               fast path
    INS               MROM
    INSB              MROM
    INSW              MROM
    INSD              MROM
    INT               MROM
    INTO              MROM
    INVD              MROM
    INVLPG            MROM
    IRET              MROM
    IRETD             MROM
    Jcc               fast path
    JCXZ              double dispatch
    JECXZ             double dispatch
    JMP               fast path
    LAHF              fast path
    LAR               MROM
    LDS               MROM
    LES               MROM
    LFS               MROM
    LGS               MROM
    LSS               MROM
    LEA               fast path
    LEAVE             double dispatch
    LGDT              MROM
    LIDT              MROM
    LLDT              MROM
    LMSW              MROM
    LODS              MROM
    LODSB             MROM
    LODSW             MROM
    LODSD             MROM
    LOOP              double dispatch
    LOOPcond          MROM
    LSL               MROM
    LTR               MROM
    MOV               fast path
    MOVCC             fast path
    MOV.CR            MROM
    MOV.DR            MROM
    MOVS              MROM
    MOVSB             MROM
    MOVSW             MROM
    MOVSD             MROM
    MOVSX             fast path
    MOVZX             fast path
    MUL               double dispatch
    NEG               fast path
    NOP               fast path
    NOT               fast path
    OR                fast path
    OUT               MROM
    OUTS              MROM
    OUTSB             MROM
    OUTSW             MROM
    OUTSD             MROM
    POP               double dispatch
    POPA              MROM
    POPAD             MROM
    POPF              MROM
    POPFD             MROM
    PUSH              fast path/double dispatch
    PUSHA             MROM
    PUSHAD            MROM
    PUSHF             fast path
    PUSHFD            fast path
    RCL               MROM
    RCR               MROM
    ROL               fast path
    ROR               fast path
    RDMSR             MROM
    REP               MROM
    REPE              MROM
    REPZ              MROM
    REPNE             MROM
    REPNZ             MROM
    RET               double dispatch
    RSM               MROM
    SAHF              fast path
    SAL               fast path
    SAR               fast path
    SHL               fast path
    SHR               fast path
    SBB               fast path
    SCAS              double dispatch
    SCASB             MROM
    SCASW             MROM
    SCASD             MROM
    SETcc             fast path
    SGDT              MROM
    SIDT              MROM
    SHLD              MROM
    SHRD              MROM
    SLDT              MROM
    SMSW              MROM
    STC               fast path
    STD               fast path
    STI               MROM
    STOS              MROM
    STOSB             MROM
    STOSW             MROM
    STOSD             MROM
    STR               MROM
    SUB               fast path
    TEST              fast path
    VERR              MROM
    VERW              MROM
    WBINVD            MROM
    WRMSR             MROM
    XADD              MROM
    XCHG              MROM
    XLAT              fast path
    XLATB             fast path
    XOR               fast path

*/



int n_RoV=0;
int n_uop=0;




int n_tmp;

struct mem_oper_desc
{
	int seg_r_v_id;
	int addr_r_v_id;
};

struct oper_desc
{
	bool b_mem;// 
	struct mem_oper_desc mem;
	int r_v_id;// reg,imm,or tmp reg holding mm valueetc.

} ;

void print_op(OPERAND_TYPE op, int n_rmbyte,struct oper_desc &o_desc )
{
	int n_seg,n_addr;

	switch( op)
	{
		case rm1:
		case rm:  // never place rm in other pos
		case rm16: 
			if ( n_rmbyte==-1)
			{
				o_desc.b_mem=true;

				if (o_desc.mem.addr_r_v_id==-1)
				{
				fprintf ( fp, "RoV r_v%d;\n"
							 "if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
							 "else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm);\n",n_RoV,n_uop,n_RoV,n_uop,n_RoV);

				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				n_uop++;

				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = 0x40|(seg==7?(stack?SS:DS):seg);// seg reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;


				n_RoV++;
				}

				if (o_desc.r_v_id==-1)
				{
				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
							n_RoV,n_RoV,n_RoV,n_tmp);


				o_desc.r_v_id=

				n_RoV++;
		
				fprintf ( fp,"uop[%d].funit=lsq;\n"
								"uop[%d].sub_op=LD;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=prefix &PREFIX_LOCK;\n"
								"uop[%d].src[0]=r_v%d;\n"
								"uop[%d].src[1]=r_v%d;\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

				n_tmp++;
				n_uop++;
				}

			}
			else
			{
				o_desc.b_mem=false;

				if (o_desc.r_v_id==-1)
				{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg =(code[0]&7)|((op_size==32)?0x20:((op_size==16)?0x10:0));\n",n_RoV,n_RoV,n_RoV);


				o_desc.r_v_id=
					n_RoV++;
				}
			}

			break;

		case rmf  :  	
			//
			// dpn't load. just 
			//

			o_desc.b_mem=true;
			if (o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp, "RoV r_v%d;\n"
							 "if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
							 "else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm);\n",n_RoV,n_uop,n_RoV,n_uop,n_RoV);
				
				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = 0x40|(seg==7?(stack?SS:DS):seg);// seg reg\n",n_RoV,n_RoV,n_RoV);
				o_desc.mem.seg_r_v_id=
				
				n_seg=n_RoV;
				n_RoV++;
			}

			if (o_desc.r_v_id==-1)
			{
				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
							n_RoV,n_RoV,n_RoV,n_tmp);


				o_desc.r_v_id=
				n_RoV++;
		
				fprintf ( fp,"uop[%d].funit=lsq;\n"
								"uop[%d].sub_op=LD;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=prefix &PREFIX_LOCK;\n"
								"uop[%d].src[0]=r_v%d;\n"
								"uop[%d].src[1]=r_v%d;\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

				n_tmp++;
				n_uop++;
			}


			break;




		case dacc :// 
		o_desc.b_mem=false;

		if (o_desc.r_v_id==-1)
		{

			
			fprintf ( fp,"RoV r_v%d;\n"
						"r_v%d.va=false;\n"
						"r_v%d.u.reg = (op_size==32)?EAX:(op_size==16)?AX:AL; \n",n_RoV,n_RoV,n_RoV);
			o_desc.r_v_id=
			n_RoV++;

		}
		break;
 		case mspu  :// push
		case mspd  :// pop   
				o_desc.b_mem=true;

				if (o_desc.mem.addr_r_v_id==-1)
				{

					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg =SP|((addr_size)?0x20:0x10);// sp/esp\n",n_RoV,n_RoV,n_RoV);

					o_desc.mem.addr_r_v_id=
					n_addr=n_RoV;

					n_RoV++;


					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = 0x40|SS;// ss\n",n_RoV,n_RoV,n_RoV);

					o_desc.mem.seg_r_v_id=
					n_seg=n_RoV;


					n_RoV++;
				}

				if (o_desc.r_v_id==-1)
				{
					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
								n_RoV,n_RoV,n_RoV,n_tmp);


					o_desc.r_v_id=
					n_RoV++;
			
					fprintf ( fp,"uop[%d].funit=lsq;\n"
								 "uop[%d].sub_op=LD;\n"
								 "uop[%d].op_size=addr_size;\n"
								 "uop[%d].prefix=0;// stack op, no lock\n"
								 "uop[%d].src[0]=r_v%d;\n"
							  	 "uop[%d].src[1]=r_v%d;\n"
								 "uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

					n_tmp++;
					n_uop++;
				}
	
		break;

		case bxp   : // gen address [ bx +al]
				o_desc.b_mem=true;
				if (o_desc.mem.addr_r_v_id==-1)
				{
					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = TMP%d|((addr_size==16)?0x10:0x20);// offet 32/16 bit\n",
								n_RoV,n_RoV,n_RoV,n_tmp);

					fprintf ( fp,"uop[%d].funit=alu;\n"
								"uop[%d].sub_op=movzx;\n"
								"uop[%d].op_size=8;\n"
								"uop[%d].prefix=0;\n"
								"uop[%d].src[0].va=false;\n"
								"uop[%d].src[0].u.reg=AL;\n"					

								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_tmp);
					n_uop ++;

					fprintf ( fp,"uop[%d].funit=alu;\n"
								"uop[%d].sub_op=add;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=0;\n"
								"uop[%d].src[0].va=false;\n"
								"uop[%d].src[0].u.reg=TMP%d|((addr_size==16)?0x10:0x20);\n"
								"uop[%d].src[1].va=false;\n"
								"uop[%d].src[1].u.reg=BX|((addr_size==16)?0x10:0x20);\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_tmp,n_uop,n_uop,n_uop,n_tmp);


					o_desc.mem.addr_r_v_id=
					n_addr=n_RoV;
					n_RoV++;

					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = 0x40|DS;// seg reg DS\n",n_RoV,n_RoV,n_RoV);

					o_desc.mem.seg_r_v_id=
  					n_seg=n_RoV;
					n_RoV++;
				}

				if (o_desc.r_v_id==-1)
				{

					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg =TMP%d|(addr_size==16?0x10:0x20);// [bx+al]\n",n_RoV,n_RoV,n_RoV,n_tmp);

					o_desc.r_v_id=
  					n_seg=n_RoV;
					n_RoV++;

				fprintf ( fp,"uop[%d].funit=lsq;\n"
								"uop[%d].sub_op=LD;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=prefix &PREFIX_LOCK;\n"
								"uop[%d].src[0]=r_v%d;\n"
								"uop[%d].src[1]=r_v%d;\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

					n_tmp++;
					n_RoV++;
				}

			break;
 
		case acc:
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = (op_size==32)?EAX:(op_size==16)?AX:AL; \n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case const_3 :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=true;\n"
							"r_v%d.u.value =3; \n",n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=

				n_RoV++;
			}
			break;

		case sreg  :  
			o_desc.b_mem=false;
			if (o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg =((code[0]>>3)&7)|0x40;// sreg\n",n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case REG   :  
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = (op_size==32)?((code[0]&7)|0x20):((code[0]&7)|0x10);// no 8 bit reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

 		case SREG   :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =((code[0]>>3)&3)|0x40;// seg reg\n");

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case reg://
			o_desc.b_mem=false;
			if (o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =(op_size==32)?(((code[0]>>3)&7)|0x20):((op_size==16)?((code[0]>>3)&7)|0x10:((code[0]>>3)&7));\n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case fs_gs    : 
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =((code[0]&0x8)?GS:FS)|0x40;// seg reg gs/fs\n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case imm      :// src1 is imm. so no rm byte
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				if ( n_rmbyte==-1 )
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =(op_size==32)?imm:(imm & 0xffff);\n",n_RoV,n_RoV,n_RoV);
				else
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =(op_size==8)?code[1+%d]:((op_size==16)?*(unsigned short *)(code+1+%d):*(unsigned long  *)(code+1+%d));\n",n_RoV,n_RoV,n_RoV,n_rmbyte,n_rmbyte,n_rmbyte);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case imm_8    : 
			o_desc.b_mem=false;
			if (o_desc.r_v_id==-1)
			{
				if ( n_rmbyte==-1 )
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =sext ?(char)imm:(unsigned char)imm;\n",n_RoV,n_RoV,n_RoV);
				else
				{
					int imm_pos=(instr_desc.src1==imm_16)?3:(n_rmbyte+ 1);
					fprintf ( fp,"RoV r_v%d;\n"
								 "r_v%d.va=true;\n"
								 "r_v%d.u.value =sext ?(char)code[%d]:code[%d];\n",n_RoV,n_RoV,n_RoV,imm_pos,imm_pos);
				}

				o_desc.r_v_id=
				n_RoV++;
			}
			break;


		case rel      :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
  				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =(op_size==8)?code[1]:((op_size==16)?*(unsigned short *)(code+1):*(unsigned long  *)(code+1));\n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;
		case rel_8    : 
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
 				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =code[1];// imm8\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;





			}
			break;
			case next_ip    : 
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
 				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =next_ip;// for relative jmp\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;
		case imm_16   : 
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				if ( n_rmbyte==-1 )
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =imm & 0xffff;\n",n_RoV,n_RoV,n_RoV);
				else
 				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =*(unsigned short *)(code+1+%d);// imm16\n",
							n_RoV,n_RoV,n_RoV,n_rmbyte);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case imm_off  : 
				o_desc.b_mem=false;

				if (o_desc.r_v_id==-1)
				{
				fprintf ( fp,"RoV r_v%d;\n"
						 "r_v%d.va=true;\n"
						 "r_v%d.u.value =(addr_size==16)?*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// offset\n",
							n_RoV,n_RoV,n_RoV);

					o_desc.r_v_id=
					n_addr=n_RoV;

					n_RoV++;
				}
			break;
		case imm_seg  : 
				o_desc.b_mem=false;

				if (o_desc.r_v_id==-1)
				{
				fprintf ( fp,"RoV r_v%d;\n"
						 "r_v%d.va=true;\n"
						 "r_v%d.u.value =(addr_size==16)?*(unsigned short *)(code+3):*(unsigned short  *)(code+5);// seg\n",
							n_RoV,n_RoV,n_RoV);

					o_desc.r_v_id=
					n_RoV++;
				}
			break;
		//case imm_far  : 
		//	o_desc.b_mem=false;
		//	if ( o_desc.r_v_id==-1)
		//	{
		//		fprintf ( fp,"RoV r_v%d;\n"
		//				 "r_v%d.va=true;\n"
		//				 "r_v%d.u.value =(addr_size==16?:*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// offset\n",
		//					n_RoV,n_RoV,n_RoV);

		//	
		//		RoVid[n_op++]=n_RoV;
		//	

		//		n_RoV++;
		//		fprintf ( fp,"RoV r_v%d;\n"
		//					 "r_v%d.va=true;\n"
		//					 "r_v%d.u.value =(addr_size==16?:*(unsigned short *)(code+3):*(unsigned long  *)(code+5);// seg\n",
		//					n_RoV,n_RoV,n_RoV);

		//		o_desc.r_v_id=
		//		RoVid[n_op++]=n_RoV;
		//		n_RoV++;
		//	}

		//	break;


	
		case mem_off   :
			o_desc.b_mem=true;
			if ( o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =(addr_size==16)?*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// direct addressing\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							  "r_v%d.va=false;\n"
							  "r_v%d.u.reg = 0x40|(seg==7?DS:seg);// seg reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;

				n_RoV++;
			}
			if (o_desc.r_v_id==-1)
			{

				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
							n_RoV,n_RoV,n_RoV,n_tmp);


				o_desc.r_v_id=
				n_RoV++;
				fprintf ( fp,"uop[%d].funit=lsq;\n"
							"uop[%d].sub_op=LD;\n"
							"uop[%d].op_size=op_size;\n"
							"uop[%d].prefix=prefix &PREFIX_LOCK;\n"
							"uop[%d].src[0]=r_v%d;\n"
							"uop[%d].src[1]=r_v%d;\n"
							"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
							n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

				n_tmp++;
				n_RoV++;
			}


			break;


		case ds_si   : 
			o_desc.b_mem=true;
			if ( o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg = SI|(addr_size==32?0x20:0x10);// seg reg\n",n_RoV,n_RoV,n_RoV);
				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							  "r_v%d.va=false;\n"
							  "r_v%d.u.reg = 0x40|DS;// seg reg DS \n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;
				n_RoV++;
			}

			if(o_desc.r_v_id==-1)
			{
			
			fprintf ( fp, "RoV r_v%d;\n"
						  "r_v%d.va=false;\n"
						  "r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			o_desc.r_v_id=

			n_RoV++;
			fprintf ( fp,"uop[%d].funit=lsq;\n"
								"uop[%d].sub_op=LD;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=prefix &PREFIX_LOCK;\n"
								"uop[%d].src[0]=r_v%d;\n"
								"uop[%d].src[1]=r_v%d;\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

			n_tmp++;
			n_uop++;
			}

			break;


		case es_di   :
			o_desc.b_mem=true;
			if ( o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg = DI|(addr_size==32?0x20:0x10);// seg reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							  "r_v%d.va=false;\n"
							  "r_v%d.u.reg = 0x40|ES;// seg reg ES \n",n_RoV,n_RoV,n_RoV);
				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;


				n_RoV++;
			}


			if ( o_desc.r_v_id==-1)
			{
			fprintf ( fp, "RoV r_v%d;\n"
						  "r_v%d.va=false;\n"
						  "r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);

			o_desc.r_v_id=
			n_RoV++;
			fprintf ( fp,"uop[%d].funit=lsq;\n"
								"uop[%d].sub_op=LD;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=prefix &PREFIX_LOCK;\n"
								"uop[%d].src[0]=r_v%d;\n"
								"uop[%d].src[1]=r_v%d;\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_seg,n_uop,n_addr,n_uop,n_tmp);

			n_tmp++;
			n_uop++;
			}

			break;

		case r16    :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =((code[1]>>3)&7)|0x10; // r16\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case cflag :// have no idea now
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.value =0x30 ;// cflag \n",
							n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;
		case const_cf :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =0x1;// mask of CF\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case const_if :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =0x200;// mask of IF\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;
		case const_df :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value = 0x400;// mask of DF\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}

			break;

		case const_1 :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value = 1;// const 1\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}

			break;
		default :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =0 ;// %s \n",
							n_RoV,n_RoV,n_RoV,operand_type_name[op]);

				o_desc.r_v_id=0;
				n_RoV++;
			}
			break;
		}
		
}
void print_dst(OPERAND_TYPE op, int n_rmbyte,struct oper_desc &o_desc )
{
	int n_seg,n_addr;

	switch( op)
	{
		case rm1:
		case rm:  // never place rm in other pos
		case rm16: 
			if ( n_rmbyte==-1)
			{
				o_desc.b_mem=true;

				if (o_desc.mem.addr_r_v_id==-1)
				{
				fprintf ( fp, "RoV r_v%d;\n"
							 "if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
							 "else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm);\n",n_RoV,n_uop,n_RoV,n_uop,n_RoV);

				o_desc.mem.addr_r_v_id=
				n_RoV++;
				n_uop++;

				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = 0x40|(seg==7?(stack?SS:DS):seg);// seg reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.seg_r_v_id=
				n_RoV++;
				}

				if (o_desc.r_v_id==-1)
				{
				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// data 32/16 bit\n",
							n_RoV,n_RoV,n_RoV,n_tmp);


				o_desc.r_v_id=
				n_RoV++;
				n_tmp++;

				}

			}
			else
			{
				o_desc.b_mem=false;

				if (o_desc.r_v_id==-1)
				{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg =(code[0]&7)|((op_size==32)?0x20:((op_size==16)?0x10:0));\n",n_RoV,n_RoV,n_RoV);


				o_desc.r_v_id=
				n_RoV++;
				}
			}

			break;

		case rmf  :  	
			//
			// dpn't load. just 
			//

			o_desc.b_mem=true;
			if (o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp, "RoV r_v%d;\n"
							 "if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
							 "else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm);\n",n_RoV,n_uop,n_RoV,n_uop,n_RoV);
				
				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = 0x40|(seg==7?(stack?SS:DS):seg);// seg reg\n",n_RoV,n_RoV,n_RoV);
				o_desc.mem.seg_r_v_id=
				
				n_seg=n_RoV;
				n_RoV++;
			}

			if (o_desc.r_v_id==-1)
			{
				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
							n_RoV,n_RoV,n_RoV,n_tmp);


				o_desc.r_v_id=
				n_RoV++;
	
				n_tmp++;
			
			}


			break;




		case dacc :// 
		o_desc.b_mem=false;

		if (o_desc.r_v_id==-1)
		{

			
			fprintf ( fp,"RoV r_v%d;\n"
						"r_v%d.va=false;\n"
						"r_v%d.u.reg = (op_size==32)?EAX:(op_size==16)?AX:AL; \n",n_RoV,n_RoV,n_RoV);
			o_desc.r_v_id=
			n_RoV++;

		}
		break;
 		case mspu  :// push
		case mspd  :// pop   
				o_desc.b_mem=true;

				if (o_desc.mem.addr_r_v_id==-1)
				{

					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg =SP|((addr_size)?0x20:0x10);// sp/esp\n",n_RoV,n_RoV,n_RoV);

					o_desc.mem.addr_r_v_id=
					n_addr=n_RoV;

					n_RoV++;


					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = 0x40|SS;// ss\n",n_RoV,n_RoV,n_RoV);

					o_desc.mem.seg_r_v_id=
					n_seg=n_RoV;


					n_RoV++;
				}

				if (o_desc.r_v_id==-1)
				{
					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
								n_RoV,n_RoV,n_RoV,n_tmp);


					o_desc.r_v_id=
					n_RoV++;
			
		

					n_tmp++;
			
				}
	
		break;

		case bxp   : // gen address [ bx +al]
				o_desc.b_mem=true;
				if (o_desc.mem.addr_r_v_id==-1)
				{
					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = TMP%d|((addr_size==16)?0x10:0x20);// offet 32/16 bit\n",
								n_RoV,n_RoV,n_RoV,n_tmp);

					fprintf ( fp,"uop[%d].funit=alu;\n"
								"uop[%d].sub_op=movzx;\n"
								"uop[%d].op_size=8;\n"
								"uop[%d].prefix=0;\n"
								"uop[%d].src[0].va=false;\n"
								"uop[%d].src[0].u.reg=AL;\n"					

								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_tmp);
					n_uop ++;

					fprintf ( fp,"uop[%d].funit=alu;\n"
								"uop[%d].sub_op=add;\n"
								"uop[%d].op_size=addr_size;\n"
								"uop[%d].prefix=0;\n"
								"uop[%d].src[0].va=false;\n"
								"uop[%d].src[0].u.reg=TMP%d|((addr_size==16)?0x10:0x20);\n"
								"uop[%d].src[1].va=false;\n"
								"uop[%d].src[1].u.reg=BX|((addr_size==16)?0x10:0x20);\n"
								"uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n",	
								n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_tmp,n_uop,n_uop,n_uop,n_tmp);


					o_desc.mem.addr_r_v_id=
					n_addr=n_RoV;
					n_RoV++;

					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg = 0x40|DS;// seg reg DS\n",n_RoV,n_RoV,n_RoV);

					o_desc.mem.seg_r_v_id=
  					n_seg=n_RoV;
					n_RoV++;
				}

				if (o_desc.r_v_id==-1)
				{

					fprintf ( fp, "RoV r_v%d;\n"
								"r_v%d.va=false;\n"
								"r_v%d.u.reg =TMP%d|(addr_size==16?0x10:0x20);// [bx+al]\n",n_RoV,n_RoV,n_RoV,n_tmp);

					o_desc.r_v_id=
  					n_seg=n_RoV;
					n_RoV++;
			

					n_tmp++;
						}

			break;
 
		case acc:
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = (op_size==32)?EAX:(op_size==16)?AX:AL; \n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case sreg  :  
			o_desc.b_mem=false;
			if (o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg =((code[0]>>3)&7)|0x40;// sreg\n",n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case REG   :  
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = (op_size==32)?((code[0]&7)|0x20):((code[0]&7)|0x10);// no 8 bit reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

 		case SREG   :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =((code[0]>>3)&3)|0x40;// seg reg\n");

				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case reg://
			o_desc.b_mem=false;
			if (o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =(op_size==32)?(((code[0]>>3)&7)|0x20):((op_size==16)?((code[0]>>3)&7)|0x10:((code[0]>>3)&7));\n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case fs_gs    : 
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =((code[0]&0x8)?GS:FS)|0x40;// seg reg gs/fs\n",n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;



	
		case mem_off   :
			o_desc.b_mem=true;
			if ( o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =(addr_size==16)?*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// direct addressing\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							  "r_v%d.va=false;\n"
							  "r_v%d.u.reg = 0x40|(seg==7?DS:seg);// seg reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;

				n_RoV++;
			}
			if (o_desc.r_v_id==-1)
			{

				fprintf ( fp, "RoV r_v%d;\n"
							"r_v%d.va=false;\n"
							"r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
							n_RoV,n_RoV,n_RoV,n_tmp);


				o_desc.r_v_id=
				n_RoV++;
				n_tmp++;
			
			}


			break;


		case ds_si   : 
			o_desc.b_mem=true;
			if ( o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg = SI|(addr_size==32?0x20:0x10);// seg reg\n",n_RoV,n_RoV,n_RoV);
				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							  "r_v%d.va=false;\n"
							  "r_v%d.u.reg = 0x40|DS;// seg reg DS \n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;
				n_RoV++;
			}

			if(o_desc.r_v_id==-1)
			{
			
			fprintf ( fp, "RoV r_v%d;\n"
						  "r_v%d.va=false;\n"
						  "r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			o_desc.r_v_id=
	
			n_RoV++;
			n_tmp++;
			}

			break;


		case es_di   :
			o_desc.b_mem=true;
			if ( o_desc.mem.addr_r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg = DI|(addr_size==32?0x20:0x10);// seg reg\n",n_RoV,n_RoV,n_RoV);

				o_desc.mem.addr_r_v_id=
				n_addr=n_RoV;

				n_RoV++;
				fprintf ( fp, "RoV r_v%d;\n"
							  "r_v%d.va=false;\n"
							  "r_v%d.u.reg = 0x40|ES;// seg reg ES \n",n_RoV,n_RoV,n_RoV);
				o_desc.mem.seg_r_v_id=
				n_seg=n_RoV;


				n_RoV++;
			}


			if ( o_desc.r_v_id==-1)
			{
			fprintf ( fp, "RoV r_v%d;\n"
						  "r_v%d.va=false;\n"
						  "r_v%d.u.reg = TMP%d|((op_size==16)?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);

			o_desc.r_v_id=
			n_RoV++;

			n_tmp++;
			}

			break;

		case r16    :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.reg =((code[1]>>3)&7)|0x10; // r16\n",
							n_RoV,n_RoV,n_RoV);
				o_desc.r_v_id=
				n_RoV++;
			}
			break;

		case cflag :// have no idea now
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=false;\n"
							 "r_v%d.u.value =0x30 ;// cflag \n",
							n_RoV,n_RoV,n_RoV);

				o_desc.r_v_id=
				n_RoV++;
			}
			break;
		

		default :
			o_desc.b_mem=false;
			if ( o_desc.r_v_id==-1)
			{
				fprintf ( fp,"RoV r_v%d;\n"
							 "r_v%d.va=true;\n"
							 "r_v%d.u.value =0 ;// bug :%s \n",
							n_RoV,n_RoV,n_RoV,operand_type_name[op]);

				o_desc.r_v_id=0;
				n_RoV++;
			}
			break;
		}
		
}



void print_uop(bool b_rm,bool b_dir)
{

	if(instr_desc.src1==rm8
		||instr_desc.src2==rm8
		||instr_desc.dst==rm8)
	{
	fprintf ( fp," op_size=8;\n");
	}
	else
	if(instr_desc.src1==rm16
		||instr_desc.src2==rm16
		||instr_desc.dst==rm16
		||instr_desc.src1==r16
		||instr_desc.src2==r16
		||instr_desc.dst==r16
		
		)
	{
	fprintf ( fp," op_size=16;\n");
	}
	else if(instr_desc.w_mask)
	{
		fprintf ( fp," op_size=(code[0]&0x%x)?data_size:8;\n",instr_desc.w_mask);
	}
	else
		fprintf ( fp," op_size=data_size;\n");


	if(instr_desc.sext_mask)
	{
		fprintf ( fp,"bool  sext=(code[0]&0x%x)!=0;\n",instr_desc.sext_mask);
	}
	else
		fprintf ( fp," bool  sext=false;\n");


	n_RoV=1;
	n_uop=0;
	n_tmp=0;




	struct oper_desc o_desc[3]; // two sources, one dest.


	//
	// parse operands to fill o_desc
	//
	OPERAND_TYPE src1,src2,dst;
	
	if (b_dir)
	{
	src1= (instr_desc.index==mov)?instr_desc.dst:instr_desc.src2;
	src2=(instr_desc.index==mov)?instr_desc.src2:instr_desc.src1;
	dst=(instr_desc.index==mov)?instr_desc.src1:instr_desc.dst;
	}
	else
	{
		src1=instr_desc.src1;
		src2=instr_desc.src2;
		dst=instr_desc.dst;
	}
	//
	// preparation for operand parse
	// calculate rm byte count
	//

	int rm_byte;
	
	
	
	 if (instr_desc.src1<rm_max
		 ||instr_desc.src2<rm_max
		 ||instr_desc.dst<rm_max)
	 {
		 rm_byte=b_rm ?-1:1;
	 }
	 else
		 rm_byte=0;  // no rm byte

	 o_desc[0].r_v_id=-1;
	 o_desc[0].mem.seg_r_v_id=-1;
	 o_desc[0].mem.addr_r_v_id=-1;
	 o_desc[1].r_v_id=-1;
	 o_desc[1].mem.seg_r_v_id=-1;
	 o_desc[1].mem.addr_r_v_id=-1;
	 o_desc[2].r_v_id=-1;
	 o_desc[2].mem.seg_r_v_id=-1;
	 o_desc[2].mem.addr_r_v_id=-1;


	 //
	 // if dst is not op1, parse dst to find reg so that mov can be translated
	 //
	 if ((op1!=instr_desc.dst)&&(none!=instr_desc.dst))
		 print_dst(dst, rm_byte,o_desc[2] );


	 //
	 // if instruction is mov, dst is a reg, put dst.r_v.reg to src1.so that LD to dst 
	 //

	 if (instr_desc.index==mov&&o_desc[2].b_mem==false)
	 {
		o_desc[0].r_v_id=o_desc[2].r_v_id;
	 }

	 //
	 // parse src1,src2
	 //
	 print_op(src1, rm_byte,o_desc[0] );
	 print_op(src2, rm_byte,o_desc[1] );


	 //
	 // if dst is  op1, copy src1 to dst
	 //
	 if (op1==instr_desc.dst)
	 {
		 o_desc[2]=o_desc[0];
	 } 
	 //if instruction is mov, dst is a mem, put src1.r_v.reg to dst.so that ST to dst
	 else if(instr_desc.index==mov&&o_desc[2].b_mem)
	 {
		o_desc[2].r_v_id=o_desc[0].r_v_id;
	 }

	 //
	 // generate funit uop
	 // skip mov if src1 or dst is mem
	 //
	 if ((instr_desc.index!=mov)
		 ||(!o_desc[2].b_mem&&!o_desc[0].b_mem))
	 {

		 if (dst!=none)
		fprintf ( fp,"uop[%d].funit=%s;\n"
					"uop[%d].sub_op=%s;\n"
					"uop[%d].op_size=op_size;\n"
					"uop[%d].prefix=0;\n"
					"uop[%d].src[0]=r_v%d;\n"
					"uop[%d].src[1]=r_v%d;\n"
					"uop[%d].dst=r_v%d.u.reg;\n",	
					n_uop,funit_name[instr_desc.funit],n_uop,instr_name[instr_desc.index],n_uop,n_uop,n_uop,o_desc[0].r_v_id,n_uop,o_desc[1].r_v_id,n_uop,o_desc[2].r_v_id);

		 else

		fprintf ( fp,"uop[%d].funit=%s;\n"
					"uop[%d].sub_op=%s;\n"
					"uop[%d].op_size=op_size;\n"
					"uop[%d].prefix=0;\n"
					"uop[%d].src[0]=r_v%d;\n"
					"uop[%d].src[1]=r_v%d;\n"
					"uop[%d].dst=-1;  // no output\n",	
					n_uop,funit_name[instr_desc.funit],n_uop,instr_name[instr_desc.index],n_uop,n_uop,n_uop,o_desc[0].r_v_id,n_uop,o_desc[1].r_v_id,n_uop,o_desc[2].r_v_id);
	n_uop ++;

	 }



	 //
	 // write back
	 //
	 if ((none!=instr_desc.dst)&&o_desc[2].b_mem)
	 {
	fprintf ( fp,"uop[%d].funit=lsq;\n"
				"uop[%d].sub_op=ST;\n"
				"uop[%d].op_size=op_size;\n"
				"uop[%d].prefix=prefix&PREFIX_LOCK;\n"
				"uop[%d].src[0]=r_v%d;// seg\n"
				"uop[%d].src[1]=r_v%d;// off\n"
				"uop[%d].src[2]=r_v%d;// data\n"	,
				n_uop,n_uop,n_uop,n_uop,n_uop,o_desc[2].mem.seg_r_v_id,n_uop,o_desc[2].mem.addr_r_v_id,n_uop,o_desc[2].r_v_id);
		n_uop ++;
	}

	fprintf(fp,"n_uop=%d;\n\n",n_uop);

}












